package com.junsi.ding.talk.util;

import java.io.IOException;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.junsi.common.constant.Constants;
import com.junsi.common.enums.DingMsgType;
import com.junsi.common.utils.JsonUtil;
import com.junsi.ding.talk.request.GetPersistentCodeRequest;
import com.junsi.ding.talk.request.GetSnsTokenRequest;
import com.junsi.ding.talk.request.SendActionCardMessageRequest;
import com.junsi.ding.talk.request.SendMarkdownMessageRequest;
import com.junsi.ding.talk.request.SendTextMessageRequest;
import com.junsi.ding.talk.result.AccessTokenResult;
import com.junsi.ding.talk.result.DeptInfoResult;
import com.junsi.ding.talk.result.GetPersistentCodeResult;
import com.junsi.ding.talk.result.GetSnsTokenResult;
import com.junsi.ding.talk.result.GetSpecUserInfoResult;
import com.junsi.ding.talk.result.UserInfoResult;
import com.junsi.ding.talk.vo.ActionCardDetailMessage;
import com.junsi.ding.talk.vo.ActionCardMessage;
import com.junsi.ding.talk.vo.Departement;
import com.junsi.ding.talk.vo.MarkdownMessage;
import com.junsi.ding.talk.vo.TextMessage;
import com.junsi.ding.talk.vo.User;

public class DingTalkClientUtil {

	private static Log logger = LogFactory.getLog(DingTalkClientUtil.class);
	
	// 企业id
	private final static String corpid = DingConfigUtil.getAuthConfig("dingding.corpid");
	// 企业密钥
	private final static String corpsecret = DingConfigUtil.getAuthConfig("dingding.corpsecret");
	// 发送通知的应用id
	private final static String agentid = DingConfigUtil.getAuthConfig("dingding.agentid");
	// 免登 appid
	private final static String appid = DingConfigUtil.getAuthConfig("dingding.appid");
	// 免登的 密钥
	private final static String appsecret = DingConfigUtil.getAuthConfig("dingding.appsecret");
	// 获取token信息url
	private final static String get_access_token_url = DingConfigUtil.getAuthConfig("dingding.get_access_token_url");
	// 获取免登陆token信息url
	private final static String get_access_token_free_login_url = DingConfigUtil.getAuthConfig("dingding.get_access_token_free_login_url");
	// 获取部门信息url
	private final static String get_dept_info_url = DingConfigUtil.getAuthConfig("dingding.get_dept_info_url");
	// 获取用户信息url
	private final static String get_user_info_url = DingConfigUtil.getAuthConfig("dingding.get_user_info_url");
	// 获取用户登录的持久授权码的url
	private final static String get_persistent_code_url = DingConfigUtil.getAuthConfig("dingding.get_persistent_code_url");
	// 获取用户授权的SNS_TOKEN的url
	private final static String get_sns_token_url = DingConfigUtil.getAuthConfig("dingding.get_sns_token_url");
	// 获取用户授权的个人信息的url
	private final static String get_spec_user_info_url = DingConfigUtil.getAuthConfig("dingding.get_spec_user_info_url");
	// 发送普通消息
	private final static String send_normal_message_url = DingConfigUtil.getAuthConfig("dingding.send_normal_message_url");
	// 发送工作通知
	private final static String send_work_notice_message_url = DingConfigUtil.getAuthConfig("dingding.send_work_notice_message_url");

	/**
	 * 获取 accesstoken
	 */
	public static String getAccessToken() {
		try {
			String url = get_access_token_url + "?corpid=" + corpid + "&corpsecret=" + corpsecret;
			String respJson = executeGetRequest(url);
			if (respJson == null) {
				return null;
			}
			AccessTokenResult accessTokenResult = JsonUtil.object(respJson, AccessTokenResult.class);
			return accessTokenResult.getAccess_token();
		} catch (IOException e) {
			logger.error("获取 accesstoken 出错", e);
		}
		return null;
	}

	/**
	 * 获取 accesstoken(免密登录用)
	 */
	public static String getAccessTokenFreeLogin() {
		try {
			String url = get_access_token_free_login_url + "?appid=" + appid + "&appsecret=" + appsecret;
			String respJson = executeGetRequest(url);
			if (respJson == null) {
				return null;
			}
			AccessTokenResult accessTokenResult = JsonUtil.object(respJson, AccessTokenResult.class);
			return accessTokenResult.getAccess_token();
		} catch (IOException e) {
			logger.error("获取 accesstoken(免密登录用)出错", e);
		}
		return null;
	}

	/**
	 * 获取 getPersistentCode(获取持久授权码)
	 */
	public static GetPersistentCodeResult getPersistentCode(String code, String access_token) {
		try {
			String url = get_persistent_code_url + "?access_token=" + access_token;
			GetPersistentCodeRequest req = new GetPersistentCodeRequest();
			req.setTmp_auth_code(code);
			String respJson = executePostRequest(url, req);
			System.out.println("授权码:" + respJson);
			if (respJson == null) {
				return null;
			}
			GetPersistentCodeResult getPersistentCodeResult = JsonUtil.object(respJson, GetPersistentCodeResult.class);
			return getPersistentCodeResult;
		} catch (IOException e) {
			logger.error("获取 getPersistentCode(获取持久授权码)失败", e);
		}
		return null;
	}

	/**
	 * 获取 getPersistentCode(获取用户授权的SNS_TOKEN)
	 */
	public static String getSnsToken(String code, String access_token) {
		try {
			GetPersistentCodeResult getPersistentCodeResult = getPersistentCode(code, access_token);
			String url = get_sns_token_url + "?access_token=" + access_token;
			GetSnsTokenRequest req = new GetSnsTokenRequest();
			req.setOpenid(getPersistentCodeResult.getOpenid());
			req.setPersistent_code(getPersistentCodeResult.getPersistent_code());
			String respJson = executePostRequest(url, req);
			if (respJson == null) {
				return null;
			}
			GetSnsTokenResult getSnsTokenResult = JsonUtil.object(respJson, GetSnsTokenResult.class);
				return getSnsTokenResult.getSns_token();
		} catch (IOException e) {
			logger.error("获取 getPersistentCode(获取用户授权的SNS_TOKEN)失败", e);
		}
		return null;
	}

	/**
	 * 获取钉钉用户授权的个人信息
	 */
	public static GetSpecUserInfoResult getSpecUserInfo(String code) {
		try {
			String access_token = getAccessTokenFreeLogin();
			String sns_token = getSnsToken(code, access_token);
			String url = get_spec_user_info_url + "?sns_token=" + sns_token;
			String respJson = executeGetRequest(url);
			if (respJson == null) {
				return null;
			}
			logger.debug("specRespjson:" + respJson);
			GetSpecUserInfoResult getSpecUserInfoResult = JsonUtil.object(respJson, GetSpecUserInfoResult.class);
			return getSpecUserInfoResult;
		} catch (IOException e) {
			logger.error("获取钉钉用户授权的个人信息失败", e);
		}
		return null;
	}

	/**
	 * 获取部门信息
	 */
	public static List<Departement> getDepetInfo(String access_token) {
		try {
			// 获取token
			// String access_token = getAccessToken();
			String url = get_dept_info_url + "?access_token=" + access_token;
			// 执行get请求
			String respJson = executeGetRequest(url);
			if (respJson == null) {
				return null;
			}
			DeptInfoResult accessTokenResult = JsonUtil.object(respJson, DeptInfoResult.class);
			return accessTokenResult.getDepartment();
		} catch (IOException e) {
			logger.error("获取部门信息失败！", e);
		}
		return null;
	}

	/**
	 * 获取人员信息(根据指定部门id获取)
	 */
	public static List<User> getUserInfo(String department_id, String access_token) {
		try {
			// 获取token
			// String access_token = getAccessToken();
			String url = get_user_info_url + "?access_token=" + access_token + "&department_id=" + department_id;
			// 执行get请求
			String respJson = executeGetRequest(url);
			if (respJson == null) {
				return null;
			}
			// 返回用户信息详情的list
			UserInfoResult userInfoResult = JsonUtil.object(respJson, UserInfoResult.class);
			return userInfoResult.getUserlist();
		} catch (IOException e) {
			logger.error("获取人员信息(根据指定部门id获取)失败！", e);
		}
		return null;
	}

	/**
	 * 发送普通消息
	 * @param touser 接收者的用户userid
	 * @param toparty 部门
	 * @param content 内容
	 * @return
	 */
	public static String sendMessageText(String touser, String toparty, String content) {
		logger.info("=====================================钉钉发送普通消息：[touser]:" + touser + ",[toparty]:" + toparty + ",[content]:" + content);
		// 获取token
		String access_token = getAccessToken();
		SendTextMessageRequest sendRequest = new SendTextMessageRequest(agentid, touser, toparty, DingMsgType.text.getCode(), new TextMessage(content));
		String url = send_normal_message_url + "?access_token=" + access_token;
		String result = executePostRequest(url, sendRequest);
		return result;
	}

	/**
	 * 发送markdown消息
	 * @param touser 接收者的用户userid
	 * @param toparty 部门
	 * @param title 标题
	 * @param content 内容
	 * @return
	 */
	public static String sendMessageMarkdown(String touser, String toparty, String title, String content) {
		logger.info("=====================================钉钉发送markdown消息：[touser]:" + touser + ",[toparty]:" + toparty + ",[title]:" + title + ",[content]:" + content);

		StringBuffer msg_content = new StringBuffer("### " + title);
		msg_content.append("\n## " + content);
		
		// 获取token
		String access_token = getAccessToken();
		SendMarkdownMessageRequest sendRequest = new SendMarkdownMessageRequest(agentid, touser, toparty, DingMsgType.markdown.getCode(), new MarkdownMessage(title, msg_content.toString()));
		String url = send_normal_message_url + "?access_token=" + access_token;
		String result = executePostRequest(url, sendRequest);
		return result;
	}

	/**
	 * 发送卡片消息
	 * @param touser
	 *            用户 多个以逗号隔开
	 * @param toparty
	 *            部门
	 * @param title
	 *            标题
	 * @param content
	 *            类容
	 * @param to_all_user
	 *            是否发送给全部用户
	 * @param jumpurl
	 *            查询跳转的url
	 * @return
	 */
	public static String sendMessageActionCard(String touser, String toparty, String title, String content, Boolean to_all_user, String jumpurl) {
		logger.info("=====================================钉钉发送卡片消息：[touser]:" + touser + ",[toparty]:" + toparty + ",[title]:" + title + ",[content]:" + content + ",[toalluser]:" + to_all_user + ",[jumpurl]:" + jumpurl);
		// 获取token
		String access_token = getAccessToken();
		// 消息 明细体
		ActionCardDetailMessage actionCardDetailMessage = new ActionCardDetailMessage(title, content, "查看详情", jumpurl);
		ActionCardMessage actionCardMessage = new ActionCardMessage("action_card", actionCardDetailMessage);
		SendActionCardMessageRequest sendRequest = new SendActionCardMessageRequest(touser, toparty, agentid, "action_card", to_all_user, actionCardMessage);
		String url = send_work_notice_message_url + "?access_token=" + access_token;
		String result = executePostRequest(url, sendRequest);
		return result;
	}

	/**
	 * 执行get请求 并返回json数据
	 * 
	 * @param url
	 * @return
	 */
	public static String executeGetRequest(String url) {
		try {
			HttpGet http = new HttpGet(url);
			HttpResponse response = HttpClients.createDefault().execute(http);
			if (response.getStatusLine().getStatusCode() == 200) {
				// 接口返回的json格式数据
				String result = EntityUtils.toString(response.getEntity(), Constants.UTF8);
				return result;
			}
		} catch (Exception e) {
			logger.error("执行get请求 并返回json数据失败！", e);
		}
		return null;
	}

	/**
	 * 执行post请求 并返回json数据
	 * 
	 * @param url
	 * @param reqJson
	 *            请求的json数据
	 * @return
	 */
	public static String executePostRequest(String url, Object reqJson) {
		try {
			HttpPost http = new HttpPost(url);
			// 请求的json对象
			http.setEntity(new StringEntity(JsonUtil.json(reqJson), Constants.UTF8));

			CloseableHttpResponse response = HttpClients.createDefault().execute(http);
			if (response.getStatusLine().getStatusCode() == 200) {
				String result = EntityUtils.toString(response.getEntity(), Constants.UTF8);
				return result;
			}
		} catch (Exception e) {
			logger.error("执行post请求 并返回json数据失败！", e);
		}
		return null;
	}


}
